import { Node, Vec2, Vec3, find, math, tween, v2, v3 } from "cc";
import { PoolManager } from "./PoolManager";
import { ZTool } from "../Utils/ZTool";


export class EffectManager {

    static MoneyPrefabPath = "Prefabs/UI/Money";

    public static MoneyEffect(worldPosition: Vec3, targetPosition: Vec3, count: number, cb: Function = null, radius: number = 70, randomRange: number = 20, endScale: Vec3 = v3(1.2, 1.2)) {
        count = ZTool.Clamp(count, 0, 100);

        let delay = 0.3;
        let parent = find("Canvas");
        let num = 0;

        for (let i = 0; i < count; i++) {
            PoolManager.GetNode(this.MoneyPrefabPath, parent).then((node: Node) => {
                node.setWorldPosition(worldPosition);
                delay += 0.01 * 70 / count;
                let randomPoint = ZTool.RandomPointAroundCenter(v2(worldPosition.x, worldPosition.y), radius);

                tween(node)
                    .delay(0.01 * i)
                    .to(0.5, { worldPosition: v3(randomPoint.x + ZTool.GetRandom(0, randomRange), randomPoint.y + ZTool.GetRandom(0, randomRange)), scale: endScale }, { easing: 'quintOut' })
                    .delay(delay)
                    .to(0.5, { worldPosition: targetPosition, scale: Vec3.ONE })
                    .call(() => {
                        PoolManager.PutNode(node);
                        num++;
                        if (num >= count) {
                            cb && cb();
                        }
                    })
                    .start();
            });

        }
    }

    public static MoneyEffect2(worldPosition: Vec3, targetPosition: Vec3, count: number, cb: Function = null, radius: number = 70, range: number = 20) {
        count = ZTool.Clamp(count, 0, 100);

        let delay = 0.3;
        let parent = find("Canvas");
        let num = 0;

        for (let i = 0; i < count; i++) {
            PoolManager.GetNode(this.MoneyPrefabPath, parent).then((node: Node) => {
                node.setWorldPosition(worldPosition);
                delay += 0.01 * 70 / count;
                let randomPoint = ZTool.RandomPointAroundCenter(v2(worldPosition.x, worldPosition.y), radius);

                tween(node)
                    .to(0.3, { worldPosition: v3(randomPoint.x + ZTool.GetRandom(0, range), randomPoint.y + ZTool.GetRandom(0, range)) }, { easing: 'sineOut' })
                    .delay(delay)
                    .to(0.5, { worldPosition: targetPosition })
                    .call(() => {
                        PoolManager.PutNode(node);
                        num++;
                        if (num >= count) {
                            cb && cb();
                        }
                    })
                    .start();
            });
        }
    }

    /**
     * 圆环的某一段弧度随机生成
     * @param worldPosition 起始点的世界坐标
     * @param targetPosition 终点的世界坐标
     * @param count 生成数量[0-100]
     * @param startPI 开始范围：一个圆的范围，最大值为2
     * @param endPI 结束范围：一个圆的范围，最大值为2
     * @param cb 结束回调
     * @param radius 距离起始点的半径
     * @param randomRange 随机位置的范围
     */
    public static MoneyEffect3(worldPosition: Vec3, targetPosition: Vec3, parent: Node, count: number, startPI: number, endPI: number, cb: Function = null, radius: number = 300, randomRange: number = 60) {
        count = ZTool.Clamp(count, 0, 100);
        let delay = 0.3;
        let num = 0;

        for (let i = 0; i < count; i++) {
            PoolManager.GetNode(this.MoneyPrefabPath, parent).then((node: Node) => {
                node.setWorldPosition(worldPosition);
                delay += 0.01 * 70 / count;
                let randomPoint = ZTool.RandomPointAroundRange(v2(worldPosition.x, worldPosition.y), radius, startPI, endPI);

                tween(node)
                    .delay(0.01 * i)
                    .to(0.5, { worldPosition: v3(randomPoint.x + ZTool.GetRandom(0, randomRange), randomPoint.y + ZTool.GetRandom(0, randomRange)) }, { easing: 'quintOut' })
                    .delay(delay)
                    .to(0.5, { worldPosition: targetPosition, scale: Vec3.ONE.clone().multiplyScalar(0.5) })
                    .call(() => {
                        PoolManager.PutNode(node);
                        num++;
                        if (num >= count) {
                            cb && cb();
                        }
                    })
                    .start();
            });
        }
    }

}